-- Decompiled with the Synapse X Luau decompiler.

local MarketplaceService = game:GetService("MarketplaceService");
local Players = game:GetService("Players");
local ServerOHOH = _G.ServerOHOH;
local OHOHEnum = ServerOHOH.load.OHOHEnum();
local function_list = ServerOHOH.function_list;
local function_manager = ServerOHOH.function_manager;
local InstanceManager = ServerOHOH.load.InstanceManager();
local DataBaseManager = ServerOHOH.load.DataBaseManager();
DataBaseManager:CreateDataBase(OHOHEnum.data_base.product_failed);
local v9 = {};
local ProductHandleData = {};
local M = ServerOHOH.class.new(script);
local u3 = {};
function MarketplaceService.ProcessReceipt(Product)
	local player = Players:GetPlayerByUserId(Product.PlayerId);
	local v13 = true;
	if not player then
		v13 = false;
	else
		local v14 = InstanceManager:FindObject(player);
		if not v14 then
			v13 = false;
		else
			local v15 = ProductHandleData[Product.ProductId];
			local l__check__16 = v15.check;
			local l__args__17 = v15.args;
			if l__check__16 and not l__check__16(v14, Product.ProductId, table.unpack(l__args__17)) then
				v13 = false;
			else
				local v18, v19 = xpcall(v15.handle, debug.traceback, v14, Product.ProductId, table.unpack(l__args__17));
				if not v18 then
					warn(v19);
					v13 = false;
				end;
			end;
		end;
	end;
	if not v13 then
		M:AddProductFailedInfo(Product.PlayerId, Product.ProductId);
	else
		M:DelProductFailedInfo(Product.PlayerId, Product.ProductId);
	end;
	local v20 = u3[Product.PlayerId];
	if v20 then
		v20.receipt = v13;
	end;
	_G.GameAnalytics:ProcessReceiptCallback(Product);
	return Enum.ProductPurchaseDecision.PurchaseGranted;
end;
MarketplaceService.PromptProductPurchaseFinished:Connect(function(p2, p3, p4)
	local v21 = u3[p2];
	u3[p2] = nil;
	if not v21 then
		warn("no pay info for user id = " .. p2 .. ",product id = " .. p3);
		return;
	end;
	v21.result = p4;

	coroutine.resume(v21.co, v21.receipt and v21.result);
	--coroutine.resume(v21.co, true);

end);
function M.CheckProductFailedInfo(self, userId, pid)
	assert(userId, "param user id is nil");
	assert(pid, "parm product id is nil");
	local v22, v23 = DataBaseManager:Load(OHOHEnum.data_base.product_failed, (string.format("%s_%s", userId, pid)));
	-- warn("BuyProduct->CheckProductFailedInfo",v22, v23)
	if not v22 then
		error(v23);
	end;
	return v23;
end;
function M.AddProductFailedInfo(self, userId, pid)
	DataBaseManager:Save(OHOHEnum.data_base.product_failed, string.format("%s_%s", userId, pid), function()
		return 1;
	end);
end;
function M.DelProductFailedInfo(self, userId, pid)
	DataBaseManager:Save(OHOHEnum.data_base.product_failed, string.format("%s_%s", userId, pid), function()
		-- print("删除历史购买记录");
	end);
end;
--self:DeliverProduct(player, id);
function M.DeliverProduct(self, player, id)
	--local v24 = nil;
	if not player:IsExist() then
		return false, "player object is not exist";
	end;
	if not player.main_inst then
		return false, "player object lost main instance";
	end;
	local phd = ProductHandleData[id];
	if phd.check and not phd.check(player, id, table.unpack(phd.args)) then
		local v29 = "user id = " .. player:GetUserId() .. " can't buy product id = " .. id .. " with check function";
		return false, v29;
	end;

	
	local success, a, b = xpcall(phd.handle, debug.traceback, player, id, table.unpack(phd.args));
	
	warn(a);
	return success, a;
end;
function M.RegistProduct(self, id, checkFuc, handleFuc, ...)
	ProductHandleData[id] = {
		check = checkFuc, 
		handle = handleFuc, 
		args = { ... }
	};
end;

function M.GetRegistProductInfo(self,id)
	return ProductHandleData[id]
end

local PayingPlayesList = {};
function M.BuyProduct(self, player, id)
	local failedData = nil;
	assert(player, "param player object is nil");
	assert(player.main_inst, "player object main instance is lost");
	assert(id, "param product id is nil");
	assert(player:IsA("Server_PlayerObject", "object must be a server player object"));
	local userId = player:GetUserId();
	local ProductHandle = ProductHandleData[id];
	assert(ProductHandle, "not regist product handle");
	if PayingPlayesList[player] then
		return false, "in pay action";
	end;

	PayingPlayesList[player] = "product";
	if ProductHandle.check and not ProductHandle.check(player, id, table.unpack(ProductHandle.args)) then
		local v35 = "user id = " .. userId .. " can't buy product id = " .. id;
		warn(v35);
		PayingPlayesList[player] = nil;
		return false, v35;
	end;

	if u3[userId] then
		warn("user id = " .. userId .. " is product_paying,retry later");
		PayingPlayesList[player] = nil;
		return false;
	end;
	--isSuccess, data
	local isSuccess = nil;
	isSuccess, failedData = xpcall(self.CheckProductFailedInfo, debug.traceback, self, userId, id);
	if not isSuccess then
		warn("data base error" .. failedData);
		PayingPlayesList[player] = nil;
		return false;
	end;

	if not failedData then

		local success, data = xpcall(MarketplaceService.PromptProductPurchase, debug.traceback, MarketplaceService, player.main_inst, id);
		if not success then
			warn(data);
			PayingPlayesList[player] = nil;

			return;
		else

			u3[userId] = {
				co = coroutine.running(), 
				id = id
			};
			local v39 = coroutine.yield();
			wait();
			PayingPlayesList[player] = nil;

			return v39;
		end;
	end;
	--提供产品
	local success, data = self:DeliverProduct(player, id);
	PayingPlayesList[player] = nil;
	if success then
		self:DelProductFailedInfo(userId, id);
	else
		self:AddProductFailedInfo(userId, id);
	end;
	return success;
end;
function M.BuyGamePass(self, p25, p26)

end;
function M.GetProductInfo(self, p28)
	return MarketplaceService:GetProductInfo(p28, Enum.InfoType.Product);
end;
function M.GetAllProductInfo(self)
	local v42 = MarketplaceService:GetDeveloperProductsAsync();
	local v43 = {};
	while true do
		for v44, v45 in pairs((v42:GetCurrentPage())) do
			v43[v45.ProductId] = v45;
		end;
		if v42.IsFinished then
			break;
		end;
		v42:AdvanceToNextPageAsync();	
	end;
	return v43;
end;
local u6 = {};
function M.RegistHandleOnBuyPremium(self, p31, p32)
	assert(p31, "param object is nil");
	assert(p32, "param handle is nil");
	u6[p32] = p31;
end;
local u7 = {};
function M.BuyPremium(self, p34)
	assert(p34, "param player object is nil");
	assert(p34.main_inst, "player object main instance is lost");
	assert(p34:IsA("Server_PlayerObject", "object must be a server player object"));
	if PayingPlayesList[p34] then
		return false, "in pay action";
	end;
	PayingPlayesList[p34] = "premium";
	local v46 = p34:GetUserId();
	if u7[v46] then
		warn("is paying for premium");
		PayingPlayesList[p34] = nil;
		return false;
	end;
	if p34:IsPremium() then
		warn("already premium");
		PayingPlayesList[p34] = nil;
		return false;
	end;
	MarketplaceService:PromptPremiumPurchase(p34.main_inst);
	u7[v46] = coroutine.running();
	local v47 = coroutine.yield();
	if v47 then
		for v48, v49 in pairs(u6) do
			v48(v49, p34);
		end;
	end;
	wait();
	PayingPlayesList[p34] = nil;
	return v47;
end;
function M.DelPayingInfo(self, p36)
	u3[p36] = nil;
	u7[p36] = nil;
end;
ServerOHOH.event_manager:RegistHandle(ServerOHOH.event_list.premium_purchase, function(player, p38)
	local v50 = player:GetUserId();
	local v51 = 0;
	while not player:IsPremium() do
		v51 = v51 + wait();
		if v51 >= 1 then
			break;
		end;	
	end;
	local v52 = player:IsPremium();
	local v53 = u7[v50];
	u7[v50] = nil;
	if v53 then
		coroutine.resume(v53, v52);
	end;
end);
function_manager:SetHandle(function_list.buy_product, function(player, p40)
	return M:BuyProduct(player, p40);
end);
function_manager:SetHandle(function_list.buy_premium, function(player)
	return M:BuyPremium(player);
end);
return M;
